package org.ccay.download.httpdownload;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 将流输出到HttpServletResponse中
 *
 */
public class DownloadOutput {
	
	public DownloadOutput() {
	}
	
	public void outputFromStream(HttpServletRequest req, HttpServletResponse resp, InputStream inputStream,
			String fileNameNew, boolean autoFormat, long fileSize) throws ServletException, IOException {
		OutputStream bos = null;
		BufferedInputStream bis = null;
		try {
			bos = resp.getOutputStream();
			bis = new BufferedInputStream(inputStream);

			if (fileSize <= 0L) {
				fileSize = bis.available();
			}
			RangeVO range = getRange(req, fileSize);

			setResponseHeader(req, resp, fileNameNew, autoFormat, range);

			flushToResponse(bos, bis, range);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException localIOException) {
				}
				inputStream = null;
			}
			if (bos != null) {
				try {
					bos.close();
				} catch (Exception localException) {
				}
				bos = null;
			}
		}
	}

	private void flushToResponse(OutputStream bos, BufferedInputStream bis, RangeVO range) throws IOException {
		long length = range.getLength();
		if (length <= 0L) {
			return;
		}

		long startPos = range.getStartPos();

		if ((startPos < 0L) || (startPos >= range.getFileSize())) {
			throw new IOException("Start position is out of correct range.");
		}

		bis.skip(startPos);

		int bufferSize = 10240;

		if (bufferSize > length) {
			bufferSize = (int) length;
		}

		byte[] buffer = new byte[bufferSize];

		int put = 0;

		while (put < length) {
			if (put + buffer.length > length) {
				buffer = new byte[(int) length - put];
			}

			int len = bis.read(buffer);

			if (len <= 0)
				break;
			bos.write(buffer, 0, len);
			try {
				bos.flush();
			} catch (IOException e) {
				break;
			}

			put += len;
		}
	}

	private void setResponseHeader(HttpServletRequest req, HttpServletResponse resp, String fileNameNew,
			boolean autoFormat, RangeVO range) {
		resp.reset();
		resp.setHeader("Accept-Ranges", "bytes");

		if (range.isHasRange()) {
			resp.setStatus(206);
			resp.setHeader("Content-Length", Long.toString(range.getLength()));

			resp.addHeader("Content-Range", "bytes " + Long.toString(range.getStartPos()) + "-"
					+ Long.toString(range.getEndPos()) + "/" + Long.toString(range.getFileSize()));
		} else {
			resp.setHeader("Content-Length", Long.toString(range.getFileSize()));
		}

		Object ct = req.getAttribute("DownloadContentType");
		if ((ct != null) && (!"application/octet-stream".equals(ct))) {
			resp.setContentType((String) ct);
		} else {
			resp.setContentType(getContentType(fileNameNew));
		}

		Object inline = req.getAttribute("DownloadInline");
		String header = (inline == null) || (Boolean.FALSE.equals(inline)) ? "attachment; " : "inline; ";

		if (autoFormat) {
			header =

					header + "filename=\"" + formatFileName(fileNameNew, req) + "\"";
		} else {
			header = header + "filename=\"" + fileNameNew + "\"";
		}

		resp.setHeader("Content-Disposition", header);
	}

	private static final Map<String, String> EXT_TO_CONTENT_TYPE = new HashMap(50);

	private String getContentType(String fileNameNew) {
		int dotPos = fileNameNew.lastIndexOf(".");
		if ((dotPos >= 1) && (dotPos != fileNameNew.length() - 1)) {
			String ext = fileNameNew.substring(dotPos + 1);

			String ct = (String) EXT_TO_CONTENT_TYPE.get(ext);
			if (ct != null) {
				return ct;
			}

			return "application/" + ext;
		}

		return "application/octet-stream";
	}

	public void outputFromBytesArray(HttpServletRequest req, HttpServletResponse resp, byte[] content,
			String fileNameNew, boolean autoFormat) throws ServletException, IOException {
		BufferedOutputStream bos = null;
		try {
			bos = new BufferedOutputStream(resp.getOutputStream());

			RangeVO range = getRange(req, content.length);

			setResponseHeader(req, resp, fileNameNew, autoFormat, range);

			bos.write(content);
		} finally {
			if (bos != null) {
				bos.close();
				bos = null;
			}
		}
	}


	public static String replaceIllegalCharacters(String s) {
		s = s.replace('\\', '_');
		s = s.replace('/', '_');
		s = s.replace(':', '_');
		s = s.replace('*', '_');
		s = s.replace('?', '_');
		s = s.replace('"', '_');
		s = s.replace('<', '_');
		s = s.replace('>', '_');
		s = s.replace('|', '_');
		s = s.replace(',', '_');
		s = s.replace(';', '_');
		s = s.replace('=', '_');

		while (s.indexOf('.') != s.lastIndexOf('.')) {
			s = s.replaceFirst("\\.", "_");
		}

		s = s.replace('—', '-');
		return s;
	}

	public static boolean isUsingTool(HttpServletRequest req) {
		String userAgent = req.getHeader("User-Agent");
		if ((userAgent.indexOf("MSIE") >= 0) || (userAgent.indexOf("Netscape") >= 0)
				|| (userAgent.indexOf("Firefox") >= 0) || (userAgent.indexOf("Opera") >= 0)
				|| (userAgent.indexOf("Chrome") >= 0) || (userAgent.indexOf("Mozilla") >= 0)) {
			return false;
		}
		return true;
	}

	public static String toUTF8String(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if ((c >= 0) && (c <= '?')) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = String.valueOf(c).getBytes("utf-8");
				} catch (UnsupportedEncodingException ex) {
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0)
						k += 256;
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		String rs = sb.toString();
		return rs;
	}

	public static String formatFileName(String s, HttpServletRequest req) {
		s = replaceIllegalCharacters(s);
		try {
			return URLEncoder.encode(s, "UTF-8").replaceAll("\\+", "%20");
		} catch (UnsupportedEncodingException e) {
		}
		return s;
	}

	private RangeVO getRange(HttpServletRequest req, long fileSize) {
		RangeVO rangeVO = new RangeVO();
		String range = req.getHeader("Range");
		long startPoint = 0L;
		long endPoint = 0L;
		if ((range != null) && (range.length() > 0)) {
			if (!range.startsWith("-")) {
				startPoint = Long
						.parseLong(range.substring(range.indexOf("bytes=") + "bytes=".length(), range.indexOf("-")));
			}

			if (!range.endsWith("-")) {
				endPoint = Long.parseLong(range.substring(range.indexOf("-") + 1));
			}
			rangeVO.setHasRange(true);
		} else {
			rangeVO.setHasRange(false);
		}

		if (endPoint == 0L) {
			endPoint = fileSize - 1L;
		}
		rangeVO.setStartPos(startPoint);
		rangeVO.setEndPos(endPoint);
		rangeVO.setFileSize(fileSize);

		return rangeVO;
	}

	class RangeVO {
		private long startPos;
		private long endPos;
		private long fileSize;
		boolean hasRange;

		RangeVO() {
		}

		public long getEndPos() {
			return this.endPos;
		}

		public long getFileSize() {
			return this.fileSize;
		}

		public long getLength() {
			return this.endPos - this.startPos + 1L;
		}

		public long getStartPos() {
			return this.startPos;
		}

		public void setEndPos(long l) {
			this.endPos = l;
		}

		public void setFileSize(long l) {
			this.fileSize = l;
		}

		public void setStartPos(long l) {
			this.startPos = l;
		}

		public boolean isHasRange() {
			return this.hasRange;
		}

		public void setHasRange(boolean b) {
			this.hasRange = b;
		}
	}

	static {
		EXT_TO_CONTENT_TYPE.put("123", "application/vnd.lotus-1-2-3");
		EXT_TO_CONTENT_TYPE.put("3dml", "text/vnd.in3d.3dml");
		EXT_TO_CONTENT_TYPE.put("3g2", "video/3gpp2");
		EXT_TO_CONTENT_TYPE.put("3gp", "video/3gpp");
		EXT_TO_CONTENT_TYPE.put("7z", "application/x-7z-compressed");
		EXT_TO_CONTENT_TYPE.put("aab", "application/x-authorware-bin");
		EXT_TO_CONTENT_TYPE.put("aac", "audio/x-aac");
		EXT_TO_CONTENT_TYPE.put("aam", "application/x-authorware-map");
		EXT_TO_CONTENT_TYPE.put("aas", "application/x-authorware-seg");
		EXT_TO_CONTENT_TYPE.put("abw", "application/x-abiword");
		EXT_TO_CONTENT_TYPE.put("ac", "application/pkix-attr-cert");
		EXT_TO_CONTENT_TYPE.put("acc", "application/vnd.americandynamics.acc");
		EXT_TO_CONTENT_TYPE.put("ace", "application/x-ace-compressed");
		EXT_TO_CONTENT_TYPE.put("acu", "application/vnd.acucobol");
		EXT_TO_CONTENT_TYPE.put("adp", "audio/adpcm");
		EXT_TO_CONTENT_TYPE.put("aep", "application/vnd.audiograph");
		EXT_TO_CONTENT_TYPE.put("afp", "application/vnd.ibm.modcap");
		EXT_TO_CONTENT_TYPE.put("ahead", "application/vnd.ahead.space");
		EXT_TO_CONTENT_TYPE.put("ai", "application/postscript");
		EXT_TO_CONTENT_TYPE.put("aif", "audio/x-aiff");
		EXT_TO_CONTENT_TYPE.put("air", "application/vnd.adobe.air-application-installer-package+zip");
		EXT_TO_CONTENT_TYPE.put("ait", "application/vnd.dvb.ait");
		EXT_TO_CONTENT_TYPE.put("ami", "application/vnd.amiga.ami");
		EXT_TO_CONTENT_TYPE.put("apk", "application/vnd.android.package-archive");
		EXT_TO_CONTENT_TYPE.put("application", "application/x-ms-application");
		EXT_TO_CONTENT_TYPE.put("apr", "application/vnd.lotus-approach");
		EXT_TO_CONTENT_TYPE.put("asf", "video/x-ms-asf");
		EXT_TO_CONTENT_TYPE.put("aso", "application/vnd.accpac.simply.aso");
		EXT_TO_CONTENT_TYPE.put("atc", "application/vnd.acucorp");
		EXT_TO_CONTENT_TYPE.put("atom", "application/atom+xml");
		EXT_TO_CONTENT_TYPE.put("atomcat", "application/atomcat+xml");
		EXT_TO_CONTENT_TYPE.put("atomsvc", "application/atomsvc+xml");
		EXT_TO_CONTENT_TYPE.put("atx", "application/vnd.antix.game-component");
		EXT_TO_CONTENT_TYPE.put("au", "audio/basic");
		EXT_TO_CONTENT_TYPE.put("avi", "video/x-msvideo");
		EXT_TO_CONTENT_TYPE.put("aw", "application/applixware");
		EXT_TO_CONTENT_TYPE.put("azf", "application/vnd.airzip.filesecure.azf");
		EXT_TO_CONTENT_TYPE.put("azs", "application/vnd.airzip.filesecure.azs");
		EXT_TO_CONTENT_TYPE.put("azw", "application/vnd.amazon.ebook");
		EXT_TO_CONTENT_TYPE.put("bcpio", "application/x-bcpio");
		EXT_TO_CONTENT_TYPE.put("bdf", "application/x-font-bdf");
		EXT_TO_CONTENT_TYPE.put("bdm", "application/vnd.syncml.dm+wbxml");
		EXT_TO_CONTENT_TYPE.put("bed", "application/vnd.realvnc.bed");
		EXT_TO_CONTENT_TYPE.put("bh2", "application/vnd.fujitsu.oasysprs");
		EXT_TO_CONTENT_TYPE.put("bin", "application/octet-stream");
		EXT_TO_CONTENT_TYPE.put("bmi", "application/vnd.bmi");
		EXT_TO_CONTENT_TYPE.put("bmp", "image/bmp");
		EXT_TO_CONTENT_TYPE.put("box", "application/vnd.previewsystems.box");
		EXT_TO_CONTENT_TYPE.put("btif", "image/prs.btif");
		EXT_TO_CONTENT_TYPE.put("bz", "application/x-bzip");
		EXT_TO_CONTENT_TYPE.put("bz2", "application/x-bzip2");
		EXT_TO_CONTENT_TYPE.put("c", "text/x-c");
		EXT_TO_CONTENT_TYPE.put("c11amc", "application/vnd.cluetrust.cartomobile-config");
		EXT_TO_CONTENT_TYPE.put("c11amz", "application/vnd.cluetrust.cartomobile-config-pkg");
		EXT_TO_CONTENT_TYPE.put("c4g", "application/vnd.clonk.c4group");
		EXT_TO_CONTENT_TYPE.put("cab", "application/vnd.ms-cab-compressed");
		EXT_TO_CONTENT_TYPE.put("car", "application/vnd.curl.car");
		EXT_TO_CONTENT_TYPE.put("cat", "application/vnd.ms-pki.seccat");
		EXT_TO_CONTENT_TYPE.put("ccxml", "application/ccxml+xml,");
		EXT_TO_CONTENT_TYPE.put("cdbcmsg", "application/vnd.contact.cmsg");
		EXT_TO_CONTENT_TYPE.put("cdkey", "application/vnd.mediastation.cdkey");
		EXT_TO_CONTENT_TYPE.put("cdmia", "application/cdmi-capability");
		EXT_TO_CONTENT_TYPE.put("cdmic", "application/cdmi-container");
		EXT_TO_CONTENT_TYPE.put("cdmid", "application/cdmi-domain");
		EXT_TO_CONTENT_TYPE.put("cdmio", "application/cdmi-object");
		EXT_TO_CONTENT_TYPE.put("cdmiq", "application/cdmi-queue");
		EXT_TO_CONTENT_TYPE.put("cdx", "chemical/x-cdx");
		EXT_TO_CONTENT_TYPE.put("cdxml", "application/vnd.chemdraw+xml");
		EXT_TO_CONTENT_TYPE.put("cdy", "application/vnd.cinderella");
		EXT_TO_CONTENT_TYPE.put("cer", "application/pkix-cert");
		EXT_TO_CONTENT_TYPE.put("cgm", "image/cgm");
		EXT_TO_CONTENT_TYPE.put("chat", "application/x-chat");
		EXT_TO_CONTENT_TYPE.put("chm", "application/vnd.ms-htmlhelp");
		EXT_TO_CONTENT_TYPE.put("chrt", "application/vnd.kde.kchart");
		EXT_TO_CONTENT_TYPE.put("cif", "chemical/x-cif");
		EXT_TO_CONTENT_TYPE.put("cii", "application/vnd.anser-web-certificate-issue-initiation");
		EXT_TO_CONTENT_TYPE.put("cil", "application/vnd.ms-artgalry");
		EXT_TO_CONTENT_TYPE.put("cla", "application/vnd.claymore");
		EXT_TO_CONTENT_TYPE.put("class", "application/java-vm");
		EXT_TO_CONTENT_TYPE.put("clkk", "application/vnd.crick.clicker.keyboard");
		EXT_TO_CONTENT_TYPE.put("clkp", "application/vnd.crick.clicker.palette");
		EXT_TO_CONTENT_TYPE.put("clkt", "application/vnd.crick.clicker.template");
		EXT_TO_CONTENT_TYPE.put("clkw", "application/vnd.crick.clicker.wordbank");
		EXT_TO_CONTENT_TYPE.put("clkx", "application/vnd.crick.clicker");
		EXT_TO_CONTENT_TYPE.put("clp", "application/x-msclip");
		EXT_TO_CONTENT_TYPE.put("cmc", "application/vnd.cosmocaller");
		EXT_TO_CONTENT_TYPE.put("cmdf", "chemical/x-cmdf");
		EXT_TO_CONTENT_TYPE.put("cml", "chemical/x-cml");
		EXT_TO_CONTENT_TYPE.put("cmp", "application/vnd.yellowriver-custom-menu");
		EXT_TO_CONTENT_TYPE.put("cmx", "image/x-cmx");
		EXT_TO_CONTENT_TYPE.put("cod", "application/vnd.rim.cod");
		EXT_TO_CONTENT_TYPE.put("cpio", "application/x-cpio");
		EXT_TO_CONTENT_TYPE.put("cpt", "application/mac-compactpro");
		EXT_TO_CONTENT_TYPE.put("crd", "application/x-mscardfile");
		EXT_TO_CONTENT_TYPE.put("crl", "application/pkix-crl");
		EXT_TO_CONTENT_TYPE.put("cryptonote", "application/vnd.rig.cryptonote");
		EXT_TO_CONTENT_TYPE.put("csh", "application/x-csh");
		EXT_TO_CONTENT_TYPE.put("csml", "chemical/x-csml");
		EXT_TO_CONTENT_TYPE.put("csp", "application/vnd.commonspace");
		EXT_TO_CONTENT_TYPE.put("css", "text/css");
		EXT_TO_CONTENT_TYPE.put("csv", "text/csv");
		EXT_TO_CONTENT_TYPE.put("cu", "application/cu-seeme");
		EXT_TO_CONTENT_TYPE.put("curl", "text/vnd.curl");
		EXT_TO_CONTENT_TYPE.put("cww", "application/prs.cww");
		EXT_TO_CONTENT_TYPE.put("dae", "model/vnd.collada+xml");
		EXT_TO_CONTENT_TYPE.put("daf", "application/vnd.mobius.daf");
		EXT_TO_CONTENT_TYPE.put("davmount", "application/davmount+xml");
		EXT_TO_CONTENT_TYPE.put("dcurl", "text/vnd.curl.dcurl");
		EXT_TO_CONTENT_TYPE.put("dd2", "application/vnd.oma.dd2+xml");
		EXT_TO_CONTENT_TYPE.put("ddd", "application/vnd.fujixerox.ddd");
		EXT_TO_CONTENT_TYPE.put("deb", "application/x-debian-package");
		EXT_TO_CONTENT_TYPE.put("der", "application/x-x509-ca-cert");
		EXT_TO_CONTENT_TYPE.put("dfac", "application/vnd.dreamfactory");
		EXT_TO_CONTENT_TYPE.put("dir", "application/x-director");
		EXT_TO_CONTENT_TYPE.put("dis", "application/vnd.mobius.dis");
		EXT_TO_CONTENT_TYPE.put("djvu", "image/vnd.djvu");
		EXT_TO_CONTENT_TYPE.put("dna", "application/vnd.dna");
		EXT_TO_CONTENT_TYPE.put("doc", "application/msword");
		EXT_TO_CONTENT_TYPE.put("docm", "application/vnd.ms-word.document.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
		EXT_TO_CONTENT_TYPE.put("dotm", "application/vnd.ms-word.template.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template");
		EXT_TO_CONTENT_TYPE.put("dp", "application/vnd.osgi.dp");
		EXT_TO_CONTENT_TYPE.put("dpg", "application/vnd.dpgraph");
		EXT_TO_CONTENT_TYPE.put("dra", "audio/vnd.dra");
		EXT_TO_CONTENT_TYPE.put("dsc", "text/prs.lines.tag");
		EXT_TO_CONTENT_TYPE.put("dssc", "application/dssc+der");
		EXT_TO_CONTENT_TYPE.put("dtb", "application/x-dtbook+xml");
		EXT_TO_CONTENT_TYPE.put("dtd", "application/xml-dtd");
		EXT_TO_CONTENT_TYPE.put("dts", "audio/vnd.dts");
		EXT_TO_CONTENT_TYPE.put("dtshd", "audio/vnd.dts.hd");
		EXT_TO_CONTENT_TYPE.put("dvi", "application/x-dvi");
		EXT_TO_CONTENT_TYPE.put("dwf", "model/vnd.dwf");
		EXT_TO_CONTENT_TYPE.put("dwg", "image/vnd.dwg");
		EXT_TO_CONTENT_TYPE.put("dxf", "image/vnd.dxf");
		EXT_TO_CONTENT_TYPE.put("dxp", "application/vnd.spotfire.dxp");
		EXT_TO_CONTENT_TYPE.put("ecelp4800", "audio/vnd.nuera.ecelp4800");
		EXT_TO_CONTENT_TYPE.put("ecelp7470", "audio/vnd.nuera.ecelp7470");
		EXT_TO_CONTENT_TYPE.put("ecelp9600", "audio/vnd.nuera.ecelp9600");
		EXT_TO_CONTENT_TYPE.put("edm", "application/vnd.novadigm.edm");
		EXT_TO_CONTENT_TYPE.put("edx", "application/vnd.novadigm.edx");
		EXT_TO_CONTENT_TYPE.put("efif", "application/vnd.picsel");
		EXT_TO_CONTENT_TYPE.put("ei6", "application/vnd.pg.osasli");
		EXT_TO_CONTENT_TYPE.put("eml", "message/rfc822");
		EXT_TO_CONTENT_TYPE.put("emma", "application/emma+xml");
		EXT_TO_CONTENT_TYPE.put("eol", "audio/vnd.digital-winds");
		EXT_TO_CONTENT_TYPE.put("eot", "application/vnd.ms-fontobject");
		EXT_TO_CONTENT_TYPE.put("epub", "application/epub+zip");
		EXT_TO_CONTENT_TYPE.put("es", "application/ecmascript");
		EXT_TO_CONTENT_TYPE.put("es3", "application/vnd.eszigno3+xml");
		EXT_TO_CONTENT_TYPE.put("esf", "application/vnd.epson.esf");
		EXT_TO_CONTENT_TYPE.put("etx", "text/x-setext");
		EXT_TO_CONTENT_TYPE.put("exe", "application/x-msdownload");
		EXT_TO_CONTENT_TYPE.put("exi", "application/exi");
		EXT_TO_CONTENT_TYPE.put("ext", "application/vnd.novadigm.ext");
		EXT_TO_CONTENT_TYPE.put("ez2", "application/vnd.ezpix-album");
		EXT_TO_CONTENT_TYPE.put("ez3", "application/vnd.ezpix-package");
		EXT_TO_CONTENT_TYPE.put("f", "text/x-fortran");
		EXT_TO_CONTENT_TYPE.put("f4v", "video/x-f4v");
		EXT_TO_CONTENT_TYPE.put("fbs", "image/vnd.fastbidsheet");
		EXT_TO_CONTENT_TYPE.put("fcs", "application/vnd.isac.fcs");
		EXT_TO_CONTENT_TYPE.put("fdf", "application/vnd.fdf");
		EXT_TO_CONTENT_TYPE.put("fe_launch", "application/vnd.denovo.fcselayout-link");
		EXT_TO_CONTENT_TYPE.put("fg5", "application/vnd.fujitsu.oasysgp");
		EXT_TO_CONTENT_TYPE.put("fh", "image/x-freehand");
		EXT_TO_CONTENT_TYPE.put("fig", "application/x-xfig");
		EXT_TO_CONTENT_TYPE.put("fli", "video/x-fli");
		EXT_TO_CONTENT_TYPE.put("flo", "application/vnd.micrografx.flo");
		EXT_TO_CONTENT_TYPE.put("flv", "video/x-flv");
		EXT_TO_CONTENT_TYPE.put("flw", "application/vnd.kde.kivio");
		EXT_TO_CONTENT_TYPE.put("flx", "text/vnd.fmi.flexstor");
		EXT_TO_CONTENT_TYPE.put("fly", "text/vnd.fly");
		EXT_TO_CONTENT_TYPE.put("fm", "application/vnd.framemaker");
		EXT_TO_CONTENT_TYPE.put("fnc", "application/vnd.frogans.fnc");
		EXT_TO_CONTENT_TYPE.put("fpx", "image/vnd.fpx");
		EXT_TO_CONTENT_TYPE.put("fsc", "application/vnd.fsc.weblaunch");
		EXT_TO_CONTENT_TYPE.put("fst", "image/vnd.fst");
		EXT_TO_CONTENT_TYPE.put("ftc", "application/vnd.fluxtime.clip");
		EXT_TO_CONTENT_TYPE.put("fti", "application/vnd.anser-web-funds-transfer-initiation");
		EXT_TO_CONTENT_TYPE.put("fvt", "video/vnd.fvt");
		EXT_TO_CONTENT_TYPE.put("fxp", "application/vnd.adobe.fxp");
		EXT_TO_CONTENT_TYPE.put("fzs", "application/vnd.fuzzysheet");
		EXT_TO_CONTENT_TYPE.put("g2w", "application/vnd.geoplan");
		EXT_TO_CONTENT_TYPE.put("g3", "image/g3fax");
		EXT_TO_CONTENT_TYPE.put("g3w", "application/vnd.geospace");
		EXT_TO_CONTENT_TYPE.put("gac", "application/vnd.groove-account");
		EXT_TO_CONTENT_TYPE.put("gdl", "model/vnd.gdl");
		EXT_TO_CONTENT_TYPE.put("geo", "application/vnd.dynageo");
		EXT_TO_CONTENT_TYPE.put("gex", "application/vnd.geometry-explorer");
		EXT_TO_CONTENT_TYPE.put("ggb", "application/vnd.geogebra.file");
		EXT_TO_CONTENT_TYPE.put("ggt", "application/vnd.geogebra.tool");
		EXT_TO_CONTENT_TYPE.put("ghf", "application/vnd.groove-help");
		EXT_TO_CONTENT_TYPE.put("gif", "image/gif");
		EXT_TO_CONTENT_TYPE.put("gim", "application/vnd.groove-identity-message");
		EXT_TO_CONTENT_TYPE.put("gmx", "application/vnd.gmx");
		EXT_TO_CONTENT_TYPE.put("gnumeric", "application/x-gnumeric");
		EXT_TO_CONTENT_TYPE.put("gph", "application/vnd.flographit");
		EXT_TO_CONTENT_TYPE.put("gqf", "application/vnd.grafeq");
		EXT_TO_CONTENT_TYPE.put("gram", "application/srgs");
		EXT_TO_CONTENT_TYPE.put("grv", "application/vnd.groove-injector");
		EXT_TO_CONTENT_TYPE.put("grxml", "application/srgs+xml");
		EXT_TO_CONTENT_TYPE.put("gsf", "application/x-font-ghostscript");
		EXT_TO_CONTENT_TYPE.put("gtar", "application/x-gtar");
		EXT_TO_CONTENT_TYPE.put("gtm", "application/vnd.groove-tool-message");
		EXT_TO_CONTENT_TYPE.put("gtw", "model/vnd.gtw");
		EXT_TO_CONTENT_TYPE.put("gv", "text/vnd.graphviz");
		EXT_TO_CONTENT_TYPE.put("gxt", "application/vnd.geonext");
		EXT_TO_CONTENT_TYPE.put("h261", "video/h261");
		EXT_TO_CONTENT_TYPE.put("h263", "video/h263");
		EXT_TO_CONTENT_TYPE.put("h264", "video/h264");
		EXT_TO_CONTENT_TYPE.put("hal", "application/vnd.hal+xml");
		EXT_TO_CONTENT_TYPE.put("hbci", "application/vnd.hbci");
		EXT_TO_CONTENT_TYPE.put("hdf", "application/x-hdf");
		EXT_TO_CONTENT_TYPE.put("hlp", "application/winhlp");
		EXT_TO_CONTENT_TYPE.put("hpgl", "application/vnd.hp-hpgl");
		EXT_TO_CONTENT_TYPE.put("hpid", "application/vnd.hp-hpid");
		EXT_TO_CONTENT_TYPE.put("hps", "application/vnd.hp-hps");
		EXT_TO_CONTENT_TYPE.put("hqx", "application/mac-binhex40");
		EXT_TO_CONTENT_TYPE.put("htke", "application/vnd.kenameaapp");
		EXT_TO_CONTENT_TYPE.put("html", "text/html");
		EXT_TO_CONTENT_TYPE.put("hvd", "application/vnd.yamaha.hv-dic");
		EXT_TO_CONTENT_TYPE.put("hvp", "application/vnd.yamaha.hv-voice");
		EXT_TO_CONTENT_TYPE.put("hvs", "application/vnd.yamaha.hv-script");
		EXT_TO_CONTENT_TYPE.put("i2g", "application/vnd.intergeo");
		EXT_TO_CONTENT_TYPE.put("icc", "application/vnd.iccprofile");
		EXT_TO_CONTENT_TYPE.put("ice", "x-conference/x-cooltalk");
		EXT_TO_CONTENT_TYPE.put("ico", "image/x-icon");
		EXT_TO_CONTENT_TYPE.put("ics", "text/calendar");
		EXT_TO_CONTENT_TYPE.put("ief", "image/ief");
		EXT_TO_CONTENT_TYPE.put("ifm", "application/vnd.shana.informed.formdata");
		EXT_TO_CONTENT_TYPE.put("igl", "application/vnd.igloader");
		EXT_TO_CONTENT_TYPE.put("igm", "application/vnd.insors.igm");
		EXT_TO_CONTENT_TYPE.put("igs", "model/iges");
		EXT_TO_CONTENT_TYPE.put("igx", "application/vnd.micrografx.igx");
		EXT_TO_CONTENT_TYPE.put("iif", "application/vnd.shana.informed.interchange");
		EXT_TO_CONTENT_TYPE.put("imp", "application/vnd.accpac.simply.imp");
		EXT_TO_CONTENT_TYPE.put("ims", "application/vnd.ms-ims");
		EXT_TO_CONTENT_TYPE.put("ipfix", "application/ipfix");
		EXT_TO_CONTENT_TYPE.put("ipk", "application/vnd.shana.informed.package");
		EXT_TO_CONTENT_TYPE.put("irm", "application/vnd.ibm.rights-management");
		EXT_TO_CONTENT_TYPE.put("irp", "application/vnd.irepository.package+xml");
		EXT_TO_CONTENT_TYPE.put("itp", "application/vnd.shana.informed.formtemplate");
		EXT_TO_CONTENT_TYPE.put("ivp", "application/vnd.immervision-ivp");
		EXT_TO_CONTENT_TYPE.put("ivu", "application/vnd.immervision-ivu");
		EXT_TO_CONTENT_TYPE.put("jad", "text/vnd.sun.j2me.app-descriptor");
		EXT_TO_CONTENT_TYPE.put("jam", "application/vnd.jam");
		EXT_TO_CONTENT_TYPE.put("jar", "application/java-archive");
		EXT_TO_CONTENT_TYPE.put("java", "text/x-java-source,java");
		EXT_TO_CONTENT_TYPE.put("jisp", "application/vnd.jisp");
		EXT_TO_CONTENT_TYPE.put("jlt", "application/vnd.hp-jlyt");
		EXT_TO_CONTENT_TYPE.put("jnlp", "application/x-java-jnlp-file");
		EXT_TO_CONTENT_TYPE.put("joda", "application/vnd.joost.joda-archive");
		EXT_TO_CONTENT_TYPE.put("jpeg", "image/jpeg");
		EXT_TO_CONTENT_TYPE.put("jpg", "image/jpeg");
		EXT_TO_CONTENT_TYPE.put("jpgv", "video/jpeg");
		EXT_TO_CONTENT_TYPE.put("jpm", "video/jpm");
		EXT_TO_CONTENT_TYPE.put("js", "application/javascript");
		EXT_TO_CONTENT_TYPE.put("json", "application/json");
		EXT_TO_CONTENT_TYPE.put("karbon", "application/vnd.kde.karbon");
		EXT_TO_CONTENT_TYPE.put("kfo", "application/vnd.kde.kformula");
		EXT_TO_CONTENT_TYPE.put("kia", "application/vnd.kidspiration");
		EXT_TO_CONTENT_TYPE.put("kml", "application/vnd.google-earth.kml+xml");
		EXT_TO_CONTENT_TYPE.put("kmz", "application/vnd.google-earth.kmz");
		EXT_TO_CONTENT_TYPE.put("kne", "application/vnd.kinar");
		EXT_TO_CONTENT_TYPE.put("kon", "application/vnd.kde.kontour");
		EXT_TO_CONTENT_TYPE.put("kpr", "application/vnd.kde.kpresenter");
		EXT_TO_CONTENT_TYPE.put("ksp", "application/vnd.kde.kspread");
		EXT_TO_CONTENT_TYPE.put("ktx", "image/ktx");
		EXT_TO_CONTENT_TYPE.put("ktz", "application/vnd.kahootz");
		EXT_TO_CONTENT_TYPE.put("kwd", "application/vnd.kde.kword");
		EXT_TO_CONTENT_TYPE.put("lasxml", "application/vnd.las.las+xml");
		EXT_TO_CONTENT_TYPE.put("latex", "application/x-latex");
		EXT_TO_CONTENT_TYPE.put("lbd", "application/vnd.llamagraphics.life-balance.desktop");
		EXT_TO_CONTENT_TYPE.put("lbe", "application/vnd.llamagraphics.life-balance.exchange+xml");
		EXT_TO_CONTENT_TYPE.put("les", "application/vnd.hhe.lesson-player");
		EXT_TO_CONTENT_TYPE.put("link66", "application/vnd.route66.link66+xml");
		EXT_TO_CONTENT_TYPE.put("lrm", "application/vnd.ms-lrm");
		EXT_TO_CONTENT_TYPE.put("ltf", "application/vnd.frogans.ltf");
		EXT_TO_CONTENT_TYPE.put("lvp", "audio/vnd.lucent.voice");
		EXT_TO_CONTENT_TYPE.put("lwp", "application/vnd.lotus-wordpro");
		EXT_TO_CONTENT_TYPE.put("m21", "application/mp21");
		EXT_TO_CONTENT_TYPE.put("m3u", "audio/x-mpegurl");
		EXT_TO_CONTENT_TYPE.put("m3u8", "application/vnd.apple.mpegurl");
		EXT_TO_CONTENT_TYPE.put("m4v", "video/x-m4v");
		EXT_TO_CONTENT_TYPE.put("ma", "application/mathematica");
		EXT_TO_CONTENT_TYPE.put("mads", "application/mads+xml");
		EXT_TO_CONTENT_TYPE.put("mag", "application/vnd.ecowin.chart");
		EXT_TO_CONTENT_TYPE.put("mathml", "application/mathml+xml");
		EXT_TO_CONTENT_TYPE.put("mbk", "application/vnd.mobius.mbk");
		EXT_TO_CONTENT_TYPE.put("mbox", "application/mbox");
		EXT_TO_CONTENT_TYPE.put("mc1", "application/vnd.medcalcdata");
		EXT_TO_CONTENT_TYPE.put("mcd", "application/vnd.mcd");
		EXT_TO_CONTENT_TYPE.put("mcurl", "text/vnd.curl.mcurl");
		EXT_TO_CONTENT_TYPE.put("mdb", "application/x-msaccess");
		EXT_TO_CONTENT_TYPE.put("mdi", "image/vnd.ms-modi");
		EXT_TO_CONTENT_TYPE.put("meta4", "application/metalink4+xml");
		EXT_TO_CONTENT_TYPE.put("mets", "application/mets+xml");
		EXT_TO_CONTENT_TYPE.put("mfm", "application/vnd.mfmp");
		EXT_TO_CONTENT_TYPE.put("mgp", "application/vnd.osgeo.mapguide.package");
		EXT_TO_CONTENT_TYPE.put("mgz", "application/vnd.proteus.magazine");
		EXT_TO_CONTENT_TYPE.put("mid", "audio/midi");
		EXT_TO_CONTENT_TYPE.put("mif", "application/vnd.mif");
		EXT_TO_CONTENT_TYPE.put("mj2", "video/mj2");
		EXT_TO_CONTENT_TYPE.put("mlp", "application/vnd.dolby.mlp");
		EXT_TO_CONTENT_TYPE.put("mmd", "application/vnd.chipnuts.karaoke-mmd");
		EXT_TO_CONTENT_TYPE.put("mmf", "application/vnd.smaf");
		EXT_TO_CONTENT_TYPE.put("mmr", "image/vnd.fujixerox.edmics-mmr");
		EXT_TO_CONTENT_TYPE.put("mny", "application/x-msmoney");
		EXT_TO_CONTENT_TYPE.put("mods", "application/mods+xml");
		EXT_TO_CONTENT_TYPE.put("movie", "video/x-sgi-movie");
		EXT_TO_CONTENT_TYPE.put("mp4", "application/mp4");
		EXT_TO_CONTENT_TYPE.put("mp4", "video/mp4");
		EXT_TO_CONTENT_TYPE.put("mp4a", "audio/mp4");
		EXT_TO_CONTENT_TYPE.put("mpc", "application/vnd.mophun.certificate");
		EXT_TO_CONTENT_TYPE.put("mpeg", "video/mpeg");
		EXT_TO_CONTENT_TYPE.put("mpga", "audio/mpeg");
		EXT_TO_CONTENT_TYPE.put("mpkg", "application/vnd.apple.installer+xml");
		EXT_TO_CONTENT_TYPE.put("mpm", "application/vnd.blueice.multipass");
		EXT_TO_CONTENT_TYPE.put("mpn", "application/vnd.mophun.application");
		EXT_TO_CONTENT_TYPE.put("mpp", "application/vnd.ms-project");
		EXT_TO_CONTENT_TYPE.put("mpy", "application/vnd.ibm.minipay");
		EXT_TO_CONTENT_TYPE.put("mqy", "application/vnd.mobius.mqy");
		EXT_TO_CONTENT_TYPE.put("mrc", "application/marc");
		EXT_TO_CONTENT_TYPE.put("mrcx", "application/marcxml+xml");
		EXT_TO_CONTENT_TYPE.put("mscml", "application/mediaservercontrol+xml");
		EXT_TO_CONTENT_TYPE.put("mseq", "application/vnd.mseq");
		EXT_TO_CONTENT_TYPE.put("msf", "application/vnd.epson.msf");
		EXT_TO_CONTENT_TYPE.put("msh", "model/mesh");
		EXT_TO_CONTENT_TYPE.put("msl", "application/vnd.mobius.msl");
		EXT_TO_CONTENT_TYPE.put("msty", "application/vnd.muvee.style");
		EXT_TO_CONTENT_TYPE.put("mts", "model/vnd.mts");
		EXT_TO_CONTENT_TYPE.put("mus", "application/vnd.musician");
		EXT_TO_CONTENT_TYPE.put("musicxml", "application/vnd.recordare.musicxml+xml");
		EXT_TO_CONTENT_TYPE.put("mvb", "application/x-msmediaview");
		EXT_TO_CONTENT_TYPE.put("mwf", "application/vnd.mfer");
		EXT_TO_CONTENT_TYPE.put("mxf", "application/mxf");
		EXT_TO_CONTENT_TYPE.put("mxl", "application/vnd.recordare.musicxml");
		EXT_TO_CONTENT_TYPE.put("mxml", "application/xv+xml");
		EXT_TO_CONTENT_TYPE.put("mxs", "application/vnd.triscape.mxs");
		EXT_TO_CONTENT_TYPE.put("mxu", "video/vnd.mpegurl");
		EXT_TO_CONTENT_TYPE.put("n-gage", "application/vnd.nokia.n-gage.symbian.install");
		EXT_TO_CONTENT_TYPE.put("n3", "text/n3");
		EXT_TO_CONTENT_TYPE.put("nbp", "application/vnd.wolfram.player");
		EXT_TO_CONTENT_TYPE.put("nc", "application/x-netcdf");
		EXT_TO_CONTENT_TYPE.put("ncx", "application/x-dtbncx+xml");
		EXT_TO_CONTENT_TYPE.put("ngdat", "application/vnd.nokia.n-gage.data");
		EXT_TO_CONTENT_TYPE.put("nlu", "application/vnd.neurolanguage.nlu");
		EXT_TO_CONTENT_TYPE.put("nml", "application/vnd.enliven");
		EXT_TO_CONTENT_TYPE.put("nnd", "application/vnd.noblenet-directory");
		EXT_TO_CONTENT_TYPE.put("nns", "application/vnd.noblenet-sealer");
		EXT_TO_CONTENT_TYPE.put("nnw", "application/vnd.noblenet-web");
		EXT_TO_CONTENT_TYPE.put("npx", "image/vnd.net-fpx");
		EXT_TO_CONTENT_TYPE.put("nsf", "application/vnd.lotus-notes");
		EXT_TO_CONTENT_TYPE.put("oa2", "application/vnd.fujitsu.oasys2");
		EXT_TO_CONTENT_TYPE.put("oa3", "application/vnd.fujitsu.oasys3");
		EXT_TO_CONTENT_TYPE.put("oas", "application/vnd.fujitsu.oasys");
		EXT_TO_CONTENT_TYPE.put("obd", "application/x-msbinder");
		EXT_TO_CONTENT_TYPE.put("oda", "application/oda");
		EXT_TO_CONTENT_TYPE.put("odb", "application/vnd.oasis.opendocument.database");
		EXT_TO_CONTENT_TYPE.put("odc", "application/vnd.oasis.opendocument.chart");
		EXT_TO_CONTENT_TYPE.put("odf", "application/vnd.oasis.opendocument.formula");
		EXT_TO_CONTENT_TYPE.put("odft", "application/vnd.oasis.opendocument.formula-template");
		EXT_TO_CONTENT_TYPE.put("odg", "application/vnd.oasis.opendocument.graphics");
		EXT_TO_CONTENT_TYPE.put("odi", "application/vnd.oasis.opendocument.image");
		EXT_TO_CONTENT_TYPE.put("odm", "application/vnd.oasis.opendocument.text-master");
		EXT_TO_CONTENT_TYPE.put("odp", "application/vnd.oasis.opendocument.presentation");
		EXT_TO_CONTENT_TYPE.put("ods", "application/vnd.oasis.opendocument.spreadsheet");
		EXT_TO_CONTENT_TYPE.put("odt", "application/vnd.oasis.opendocument.text");
		EXT_TO_CONTENT_TYPE.put("oga", "audio/ogg");
		EXT_TO_CONTENT_TYPE.put("ogv", "video/ogg");
		EXT_TO_CONTENT_TYPE.put("ogx", "application/ogg");
		EXT_TO_CONTENT_TYPE.put("onetoc", "application/onenote");
		EXT_TO_CONTENT_TYPE.put("opf", "application/oebps-package+xml");
		EXT_TO_CONTENT_TYPE.put("org", "application/vnd.lotus-organizer");
		EXT_TO_CONTENT_TYPE.put("osf", "application/vnd.yamaha.openscoreformat");
		EXT_TO_CONTENT_TYPE.put("osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml");
		EXT_TO_CONTENT_TYPE.put("otc", "application/vnd.oasis.opendocument.chart-template");
		EXT_TO_CONTENT_TYPE.put("otf", "application/x-font-otf");
		EXT_TO_CONTENT_TYPE.put("otg", "application/vnd.oasis.opendocument.graphics-template");
		EXT_TO_CONTENT_TYPE.put("oth", "application/vnd.oasis.opendocument.text-web");
		EXT_TO_CONTENT_TYPE.put("oti", "application/vnd.oasis.opendocument.image-template");
		EXT_TO_CONTENT_TYPE.put("otp", "application/vnd.oasis.opendocument.presentation-template");
		EXT_TO_CONTENT_TYPE.put("ots", "application/vnd.oasis.opendocument.spreadsheet-template");
		EXT_TO_CONTENT_TYPE.put("ott", "application/vnd.oasis.opendocument.text-template");
		EXT_TO_CONTENT_TYPE.put("oxt", "application/vnd.openofficeorg.extension");
		EXT_TO_CONTENT_TYPE.put("p", "text/x-pascal");
		EXT_TO_CONTENT_TYPE.put("p10", "application/pkcs10");
		EXT_TO_CONTENT_TYPE.put("p12", "application/x-pkcs12");
		EXT_TO_CONTENT_TYPE.put("p7b", "application/x-pkcs7-certificates");
		EXT_TO_CONTENT_TYPE.put("p7m", "application/pkcs7-mime");
		EXT_TO_CONTENT_TYPE.put("p7r", "application/x-pkcs7-certreqresp");
		EXT_TO_CONTENT_TYPE.put("p7s", "application/pkcs7-signature");
		EXT_TO_CONTENT_TYPE.put("p8", "application/pkcs8");
		EXT_TO_CONTENT_TYPE.put("par", "text/plain-bas");
		EXT_TO_CONTENT_TYPE.put("paw", "application/vnd.pawaafile");
		EXT_TO_CONTENT_TYPE.put("pbd", "application/vnd.powerbuilder6");
		EXT_TO_CONTENT_TYPE.put("pbm", "image/x-portable-bitmap");
		EXT_TO_CONTENT_TYPE.put("pcf", "application/x-font-pcf");
		EXT_TO_CONTENT_TYPE.put("pcl", "application/vnd.hp-pcl");
		EXT_TO_CONTENT_TYPE.put("pclxl", "application/vnd.hp-pclxl");
		EXT_TO_CONTENT_TYPE.put("pcurl", "application/vnd.curl.pcurl");
		EXT_TO_CONTENT_TYPE.put("pcx", "image/x-pcx");
		EXT_TO_CONTENT_TYPE.put("pdb", "application/vnd.palm");
		EXT_TO_CONTENT_TYPE.put("pdf", "application/pdf");
		EXT_TO_CONTENT_TYPE.put("pfa", "application/x-font-type1");
		EXT_TO_CONTENT_TYPE.put("pfr", "application/font-tdpfr");
		EXT_TO_CONTENT_TYPE.put("pgm", "image/x-portable-graymap");
		EXT_TO_CONTENT_TYPE.put("pgn", "application/x-chess-pgn");
		EXT_TO_CONTENT_TYPE.put("pgp", "application/pgp-signature");
		EXT_TO_CONTENT_TYPE.put("pic", "image/x-pict");
		EXT_TO_CONTENT_TYPE.put("pki", "application/pkixcmp");
		EXT_TO_CONTENT_TYPE.put("pkipath", "application/pkix-pkipath");
		EXT_TO_CONTENT_TYPE.put("plb", "application/vnd.3gpp.pic-bw-large");
		EXT_TO_CONTENT_TYPE.put("plc", "application/vnd.mobius.plc");
		EXT_TO_CONTENT_TYPE.put("plf", "application/vnd.pocketlearn");
		EXT_TO_CONTENT_TYPE.put("pls", "application/pls+xml");
		EXT_TO_CONTENT_TYPE.put("pml", "application/vnd.ctc-posml");
		EXT_TO_CONTENT_TYPE.put("png", "image/png");
		EXT_TO_CONTENT_TYPE.put("pnm", "image/x-portable-anymap");
		EXT_TO_CONTENT_TYPE.put("portpkg", "application/vnd.macports.portpkg");
		EXT_TO_CONTENT_TYPE.put("potm", "application/vnd.ms-powerpoint.template.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("potx", "application/vnd.openxmlformats-officedocument.presentationml.template");
		EXT_TO_CONTENT_TYPE.put("ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("ppd", "application/vnd.cups-ppd");
		EXT_TO_CONTENT_TYPE.put("ppm", "image/x-portable-pixmap");
		EXT_TO_CONTENT_TYPE.put("ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow");
		EXT_TO_CONTENT_TYPE.put("ppt", "application/vnd.ms-powerpoint");
		EXT_TO_CONTENT_TYPE.put("pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
		EXT_TO_CONTENT_TYPE.put("prc", "application/x-mobipocket-ebook");
		EXT_TO_CONTENT_TYPE.put("pre", "application/vnd.lotus-freelance");
		EXT_TO_CONTENT_TYPE.put("prf", "application/pics-rules");
		EXT_TO_CONTENT_TYPE.put("psb", "application/vnd.3gpp.pic-bw-small");
		EXT_TO_CONTENT_TYPE.put("psd", "image/vnd.adobe.photoshop");
		EXT_TO_CONTENT_TYPE.put("psf", "application/x-font-linux-psf");
		EXT_TO_CONTENT_TYPE.put("pskcxml", "application/pskc+xml");
		EXT_TO_CONTENT_TYPE.put("ptid", "application/vnd.pvi.ptid1");
		EXT_TO_CONTENT_TYPE.put("pub", "application/x-mspublisher");
		EXT_TO_CONTENT_TYPE.put("pvb", "application/vnd.3gpp.pic-bw-var");
		EXT_TO_CONTENT_TYPE.put("pwn", "application/vnd.3m.post-it-notes");
		EXT_TO_CONTENT_TYPE.put("pya", "audio/vnd.ms-playready.media.pya");
		EXT_TO_CONTENT_TYPE.put("pyv", "video/vnd.ms-playready.media.pyv");
		EXT_TO_CONTENT_TYPE.put("qam", "application/vnd.epson.quickanime");
		EXT_TO_CONTENT_TYPE.put("qbo", "application/vnd.intu.qbo");
		EXT_TO_CONTENT_TYPE.put("qfx", "application/vnd.intu.qfx");
		EXT_TO_CONTENT_TYPE.put("qps", "application/vnd.publishare-delta-tree");
		EXT_TO_CONTENT_TYPE.put("qt", "video/quicktime");
		EXT_TO_CONTENT_TYPE.put("qxd", "application/vnd.quark.quarkxpress");
		EXT_TO_CONTENT_TYPE.put("ram", "audio/x-pn-realaudio");
		EXT_TO_CONTENT_TYPE.put("rar", "application/rar");
		EXT_TO_CONTENT_TYPE.put("ras", "image/x-cmu-raster");
		EXT_TO_CONTENT_TYPE.put("rcprofile", "application/vnd.ipunplugged.rcprofile");
		EXT_TO_CONTENT_TYPE.put("rdf", "application/rdf+xml");
		EXT_TO_CONTENT_TYPE.put("rdz", "application/vnd.data-vision.rdz");
		EXT_TO_CONTENT_TYPE.put("rep", "application/vnd.businessobjects");
		EXT_TO_CONTENT_TYPE.put("res", "application/x-dtbresource+xml");
		EXT_TO_CONTENT_TYPE.put("rgb", "image/x-rgb");
		EXT_TO_CONTENT_TYPE.put("rif", "application/reginfo+xml");
		EXT_TO_CONTENT_TYPE.put("rip", "audio/vnd.rip");
		EXT_TO_CONTENT_TYPE.put("rl", "application/resource-lists+xml");
		EXT_TO_CONTENT_TYPE.put("rlc", "image/vnd.fujixerox.edmics-rlc");
		EXT_TO_CONTENT_TYPE.put("rld", "application/resource-lists-diff+xml");
		EXT_TO_CONTENT_TYPE.put("rm", "application/vnd.rn-realmedia");
		EXT_TO_CONTENT_TYPE.put("rmp", "audio/x-pn-realaudio-plugin");
		EXT_TO_CONTENT_TYPE.put("rms", "application/vnd.jcp.javame.midlet-rms");
		EXT_TO_CONTENT_TYPE.put("rnc", "application/relax-ng-compact-syntax");
		EXT_TO_CONTENT_TYPE.put("rp9", "application/vnd.cloanto.rp9");
		EXT_TO_CONTENT_TYPE.put("rpss", "application/vnd.nokia.radio-presets");
		EXT_TO_CONTENT_TYPE.put("rpst", "application/vnd.nokia.radio-preset");
		EXT_TO_CONTENT_TYPE.put("rq", "application/sparql-query");
		EXT_TO_CONTENT_TYPE.put("rs", "application/rls-services+xml");
		EXT_TO_CONTENT_TYPE.put("rsd", "application/rsd+xml");
		EXT_TO_CONTENT_TYPE.put("rss", "application/rss+xml");
		EXT_TO_CONTENT_TYPE.put("rtf", "application/rtf");
		EXT_TO_CONTENT_TYPE.put("rtx", "text/richtext");
		EXT_TO_CONTENT_TYPE.put("s", "text/x-asm");
		EXT_TO_CONTENT_TYPE.put("saf", "application/vnd.yamaha.smaf-audio");
		EXT_TO_CONTENT_TYPE.put("sbml", "application/sbml+xml");
		EXT_TO_CONTENT_TYPE.put("sc", "application/vnd.ibm.secure-container");
		EXT_TO_CONTENT_TYPE.put("scd", "application/x-msschedule");
		EXT_TO_CONTENT_TYPE.put("scm", "application/vnd.lotus-screencam");
		EXT_TO_CONTENT_TYPE.put("scq", "application/scvp-cv-request");
		EXT_TO_CONTENT_TYPE.put("scs", "application/scvp-cv-response");
		EXT_TO_CONTENT_TYPE.put("scurl", "text/vnd.curl.scurl");
		EXT_TO_CONTENT_TYPE.put("sda", "application/vnd.stardivision.draw");
		EXT_TO_CONTENT_TYPE.put("sdc", "application/vnd.stardivision.calc");
		EXT_TO_CONTENT_TYPE.put("sdd", "application/vnd.stardivision.impress");
		EXT_TO_CONTENT_TYPE.put("sdkm", "application/vnd.solent.sdkm+xml");
		EXT_TO_CONTENT_TYPE.put("sdp", "application/sdp");
		EXT_TO_CONTENT_TYPE.put("sdw", "application/vnd.stardivision.writer");
		EXT_TO_CONTENT_TYPE.put("see", "application/vnd.seemail");
		EXT_TO_CONTENT_TYPE.put("seed", "application/vnd.fdsn.seed");
		EXT_TO_CONTENT_TYPE.put("sema", "application/vnd.sema");
		EXT_TO_CONTENT_TYPE.put("semd", "application/vnd.semd");
		EXT_TO_CONTENT_TYPE.put("semf", "application/vnd.semf");
		EXT_TO_CONTENT_TYPE.put("ser", "application/java-serialized-object");
		EXT_TO_CONTENT_TYPE.put("setpay", "application/set-payment-initiation");
		EXT_TO_CONTENT_TYPE.put("setreg", "application/set-registration-initiation");
		EXT_TO_CONTENT_TYPE.put("sfd-hdstx", "application/vnd.hydrostatix.sof-data");
		EXT_TO_CONTENT_TYPE.put("sfs", "application/vnd.spotfire.sfs");
		EXT_TO_CONTENT_TYPE.put("sgl", "application/vnd.stardivision.writer-global");
		EXT_TO_CONTENT_TYPE.put("sgml", "text/sgml");
		EXT_TO_CONTENT_TYPE.put("sh", "application/x-sh");
		EXT_TO_CONTENT_TYPE.put("shar", "application/x-shar");
		EXT_TO_CONTENT_TYPE.put("shf", "application/shf+xml");
		EXT_TO_CONTENT_TYPE.put("sis", "application/vnd.symbian.install");
		EXT_TO_CONTENT_TYPE.put("sit", "application/x-stuffit");
		EXT_TO_CONTENT_TYPE.put("sitx", "application/x-stuffitx");
		EXT_TO_CONTENT_TYPE.put("skp", "application/vnd.koan");
		EXT_TO_CONTENT_TYPE.put("sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide");
		EXT_TO_CONTENT_TYPE.put("slt", "application/vnd.epson.salt");
		EXT_TO_CONTENT_TYPE.put("sm", "application/vnd.stepmania.stepchart");
		EXT_TO_CONTENT_TYPE.put("smf", "application/vnd.stardivision.math");
		EXT_TO_CONTENT_TYPE.put("smi", "application/smil+xml");
		EXT_TO_CONTENT_TYPE.put("snf", "application/x-font-snf");
		EXT_TO_CONTENT_TYPE.put("spf", "application/vnd.yamaha.smaf-phrase");
		EXT_TO_CONTENT_TYPE.put("spl", "application/x-futuresplash");
		EXT_TO_CONTENT_TYPE.put("spot", "text/vnd.in3d.spot");
		EXT_TO_CONTENT_TYPE.put("spp", "application/scvp-vp-response");
		EXT_TO_CONTENT_TYPE.put("spq", "application/scvp-vp-request");
		EXT_TO_CONTENT_TYPE.put("src", "application/x-wais-source");
		EXT_TO_CONTENT_TYPE.put("sru", "application/sru+xml");
		EXT_TO_CONTENT_TYPE.put("srx", "application/sparql-results+xml");
		EXT_TO_CONTENT_TYPE.put("sse", "application/vnd.kodak-descriptor");
		EXT_TO_CONTENT_TYPE.put("ssf", "application/vnd.epson.ssf");
		EXT_TO_CONTENT_TYPE.put("ssml", "application/ssml+xml");
		EXT_TO_CONTENT_TYPE.put("st", "application/vnd.sailingtracker.track");
		EXT_TO_CONTENT_TYPE.put("stc", "application/vnd.sun.xml.calc.template");
		EXT_TO_CONTENT_TYPE.put("std", "application/vnd.sun.xml.draw.template");
		EXT_TO_CONTENT_TYPE.put("stf", "application/vnd.wt.stf");
		EXT_TO_CONTENT_TYPE.put("sti", "application/vnd.sun.xml.impress.template");
		EXT_TO_CONTENT_TYPE.put("stk", "application/hyperstudio");
		EXT_TO_CONTENT_TYPE.put("stl", "application/vnd.ms-pki.stl");
		EXT_TO_CONTENT_TYPE.put("str", "application/vnd.pg.format");
		EXT_TO_CONTENT_TYPE.put("stw", "application/vnd.sun.xml.writer.template");
		EXT_TO_CONTENT_TYPE.put("sub", "image/vnd.dvb.subtitle");
		EXT_TO_CONTENT_TYPE.put("sus", "application/vnd.sus-calendar");
		EXT_TO_CONTENT_TYPE.put("sv4cpio", "application/x-sv4cpio");
		EXT_TO_CONTENT_TYPE.put("sv4crc", "application/x-sv4crc");
		EXT_TO_CONTENT_TYPE.put("svc", "application/vnd.dvb.service");
		EXT_TO_CONTENT_TYPE.put("svd", "application/vnd.svd");
		EXT_TO_CONTENT_TYPE.put("svg", "image/svg+xml");
		EXT_TO_CONTENT_TYPE.put("swf", "application/x-shockwave-flash");
		EXT_TO_CONTENT_TYPE.put("swi", "application/vnd.aristanetworks.swi");
		EXT_TO_CONTENT_TYPE.put("sxc", "application/vnd.sun.xml.calc");
		EXT_TO_CONTENT_TYPE.put("sxd", "application/vnd.sun.xml.draw");
		EXT_TO_CONTENT_TYPE.put("sxg", "application/vnd.sun.xml.writer.global");
		EXT_TO_CONTENT_TYPE.put("sxi", "application/vnd.sun.xml.impress");
		EXT_TO_CONTENT_TYPE.put("sxm", "application/vnd.sun.xml.math");
		EXT_TO_CONTENT_TYPE.put("sxw", "application/vnd.sun.xml.writer");
		EXT_TO_CONTENT_TYPE.put("t", "text/troff");
		EXT_TO_CONTENT_TYPE.put("tao", "application/vnd.tao.intent-module-archive");
		EXT_TO_CONTENT_TYPE.put("tar", "application/x-tar");
		EXT_TO_CONTENT_TYPE.put("tcap", "application/vnd.3gpp2.tcap");
		EXT_TO_CONTENT_TYPE.put("tcl", "application/x-tcl");
		EXT_TO_CONTENT_TYPE.put("teacher", "application/vnd.smart.teacher");
		EXT_TO_CONTENT_TYPE.put("tei", "application/tei+xml");
		EXT_TO_CONTENT_TYPE.put("tex", "application/x-tex");
		EXT_TO_CONTENT_TYPE.put("texinfo", "application/x-texinfo");
		EXT_TO_CONTENT_TYPE.put("tfi", "application/thraud+xml");
		EXT_TO_CONTENT_TYPE.put("tfm", "application/x-tex-tfm");
		EXT_TO_CONTENT_TYPE.put("thmx", "application/vnd.ms-officetheme");
		EXT_TO_CONTENT_TYPE.put("tiff", "image/tiff");
		EXT_TO_CONTENT_TYPE.put("tif", "image/tiff");
		EXT_TO_CONTENT_TYPE.put("tmo", "application/vnd.tmobile-livetv");
		EXT_TO_CONTENT_TYPE.put("torrent", "application/x-bittorrent");
		EXT_TO_CONTENT_TYPE.put("tpl", "application/vnd.groove-tool-template");
		EXT_TO_CONTENT_TYPE.put("tpt", "application/vnd.trid.tpt");
		EXT_TO_CONTENT_TYPE.put("tra", "application/vnd.trueapp");
		EXT_TO_CONTENT_TYPE.put("trm", "application/x-msterminal");
		EXT_TO_CONTENT_TYPE.put("tsd", "application/timestamped-data");
		EXT_TO_CONTENT_TYPE.put("tsv", "text/tab-separated-values");
		EXT_TO_CONTENT_TYPE.put("ttf", "application/x-font-ttf");
		EXT_TO_CONTENT_TYPE.put("ttl", "text/turtle");
		EXT_TO_CONTENT_TYPE.put("twd", "application/vnd.simtech-mindmapper");
		EXT_TO_CONTENT_TYPE.put("txd", "application/vnd.genomatix.tuxedo");
		EXT_TO_CONTENT_TYPE.put("txf", "application/vnd.mobius.txf");
		EXT_TO_CONTENT_TYPE.put("txt", "text/plain");
		EXT_TO_CONTENT_TYPE.put("ufd", "application/vnd.ufdl");
		EXT_TO_CONTENT_TYPE.put("umj", "application/vnd.umajin");
		EXT_TO_CONTENT_TYPE.put("unityweb", "application/vnd.unity");
		EXT_TO_CONTENT_TYPE.put("uoml", "application/vnd.uoml+xml");
		EXT_TO_CONTENT_TYPE.put("uri", "text/uri-list");
		EXT_TO_CONTENT_TYPE.put("ustar", "application/x-ustar");
		EXT_TO_CONTENT_TYPE.put("utz", "application/vnd.uiq.theme");
		EXT_TO_CONTENT_TYPE.put("uu", "text/x-uuencode");
		EXT_TO_CONTENT_TYPE.put("uva", "audio/vnd.dece.audio");
		EXT_TO_CONTENT_TYPE.put("uvh", "video/vnd.dece.hd");
		EXT_TO_CONTENT_TYPE.put("uvi", "image/vnd.dece.graphic");
		EXT_TO_CONTENT_TYPE.put("uvm", "video/vnd.dece.mobile");
		EXT_TO_CONTENT_TYPE.put("uvp", "video/vnd.dece.pd");
		EXT_TO_CONTENT_TYPE.put("uvs", "video/vnd.dece.sd");
		EXT_TO_CONTENT_TYPE.put("uvu", "video/vnd.uvvu.mp4");
		EXT_TO_CONTENT_TYPE.put("uvv", "video/vnd.dece.video");
		EXT_TO_CONTENT_TYPE.put("vcd", "application/x-cdlink");
		EXT_TO_CONTENT_TYPE.put("vcf", "text/x-vcard");
		EXT_TO_CONTENT_TYPE.put("vcg", "application/vnd.groove-vcard");
		EXT_TO_CONTENT_TYPE.put("vcs", "text/x-vcalendar");
		EXT_TO_CONTENT_TYPE.put("vcx", "application/vnd.vcx");
		EXT_TO_CONTENT_TYPE.put("vis", "application/vnd.visionary");
		EXT_TO_CONTENT_TYPE.put("viv", "video/vnd.vivo");
		EXT_TO_CONTENT_TYPE.put("vsd", "application/vnd.visio");
		EXT_TO_CONTENT_TYPE.put("vsf", "application/vnd.vsf");
		EXT_TO_CONTENT_TYPE.put("vtu", "model/vnd.vtu");
		EXT_TO_CONTENT_TYPE.put("vxml", "application/voicexml+xml");
		EXT_TO_CONTENT_TYPE.put("wad", "application/x-doom");
		EXT_TO_CONTENT_TYPE.put("wav", "audio/x-wav");
		EXT_TO_CONTENT_TYPE.put("wax", "audio/x-ms-wax");
		EXT_TO_CONTENT_TYPE.put("wbmp", "image/vnd.wap.wbmp");
		EXT_TO_CONTENT_TYPE.put("wbs", "application/vnd.criticaltools.wbs+xml");
		EXT_TO_CONTENT_TYPE.put("wbxml", "application/vnd.wap.wbxml");
		EXT_TO_CONTENT_TYPE.put("weba", "audio/webm");
		EXT_TO_CONTENT_TYPE.put("webm", "video/webm");
		EXT_TO_CONTENT_TYPE.put("webp", "image/webp");
		EXT_TO_CONTENT_TYPE.put("wg", "application/vnd.pmi.widget");
		EXT_TO_CONTENT_TYPE.put("wgt", "application/widget");
		EXT_TO_CONTENT_TYPE.put("wm", "video/x-ms-wm");
		EXT_TO_CONTENT_TYPE.put("wma", "audio/x-ms-wma");
		EXT_TO_CONTENT_TYPE.put("wmd", "application/x-ms-wmd");
		EXT_TO_CONTENT_TYPE.put("wmf", "application/x-msmetafile");
		EXT_TO_CONTENT_TYPE.put("wml", "text/vnd.wap.wml");
		EXT_TO_CONTENT_TYPE.put("wmlc", "application/vnd.wap.wmlc");
		EXT_TO_CONTENT_TYPE.put("wmls", "text/vnd.wap.wmlscript");
		EXT_TO_CONTENT_TYPE.put("wmlsc", "application/vnd.wap.wmlscriptc");
		EXT_TO_CONTENT_TYPE.put("wmv", "video/x-ms-wmv");
		EXT_TO_CONTENT_TYPE.put("wmx", "video/x-ms-wmx");
		EXT_TO_CONTENT_TYPE.put("wmz", "application/x-ms-wmz");
		EXT_TO_CONTENT_TYPE.put("woff", "application/x-font-woff");
		EXT_TO_CONTENT_TYPE.put("wpd", "application/vnd.wordperfect");
		EXT_TO_CONTENT_TYPE.put("wpl", "application/vnd.ms-wpl");
		EXT_TO_CONTENT_TYPE.put("wps", "application/vnd.ms-works");
		EXT_TO_CONTENT_TYPE.put("wqd", "application/vnd.wqd");
		EXT_TO_CONTENT_TYPE.put("wri", "application/x-mswrite");
		EXT_TO_CONTENT_TYPE.put("wrl", "model/vrml");
		EXT_TO_CONTENT_TYPE.put("wsdl", "application/wsdl+xml");
		EXT_TO_CONTENT_TYPE.put("wspolicy", "application/wspolicy+xml");
		EXT_TO_CONTENT_TYPE.put("wtb", "application/vnd.webturbo");
		EXT_TO_CONTENT_TYPE.put("wvx", "video/x-ms-wvx");
		EXT_TO_CONTENT_TYPE.put("x3d", "application/vnd.hzn-3d-crossword");
		EXT_TO_CONTENT_TYPE.put("xap", "application/x-silverlight-app");
		EXT_TO_CONTENT_TYPE.put("xar", "application/vnd.xara");
		EXT_TO_CONTENT_TYPE.put("xbap", "application/x-ms-xbap");
		EXT_TO_CONTENT_TYPE.put("xbd", "application/vnd.fujixerox.docuworks.binder");
		EXT_TO_CONTENT_TYPE.put("xbm", "image/x-xbitmap");
		EXT_TO_CONTENT_TYPE.put("xdf", "application/xcap-diff+xml");
		EXT_TO_CONTENT_TYPE.put("xdm", "application/vnd.syncml.dm+xml");
		EXT_TO_CONTENT_TYPE.put("xdp", "application/vnd.adobe.xdp+xml");
		EXT_TO_CONTENT_TYPE.put("xdssc", "application/dssc+xml");
		EXT_TO_CONTENT_TYPE.put("xdw", "application/vnd.fujixerox.docuworks");
		EXT_TO_CONTENT_TYPE.put("xenc", "application/xenc+xml");
		EXT_TO_CONTENT_TYPE.put("xer", "application/patch-ops-error+xml");
		EXT_TO_CONTENT_TYPE.put("xfdf", "application/vnd.adobe.xfdf");
		EXT_TO_CONTENT_TYPE.put("xfdl", "application/vnd.xfdl");
		EXT_TO_CONTENT_TYPE.put("xhtml", "application/xhtml+xml");
		EXT_TO_CONTENT_TYPE.put("xif", "image/vnd.xiff");
		EXT_TO_CONTENT_TYPE.put("xlam", "application/vnd.ms-excel.addin.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("xls", "application/vnd.ms-excel");
		EXT_TO_CONTENT_TYPE.put("xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("xlsm", "application/vnd.ms-excel.sheet.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		EXT_TO_CONTENT_TYPE.put("xltm", "application/vnd.ms-excel.template.macroenabled.12");
		EXT_TO_CONTENT_TYPE.put("xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template");
		EXT_TO_CONTENT_TYPE.put("xml", "application/xml");
		EXT_TO_CONTENT_TYPE.put("xo", "application/vnd.olpc-sugar");
		EXT_TO_CONTENT_TYPE.put("xop", "application/xop+xml");
		EXT_TO_CONTENT_TYPE.put("xpi", "application/x-xpinstall");
		EXT_TO_CONTENT_TYPE.put("xpm", "image/x-xpixmap");
		EXT_TO_CONTENT_TYPE.put("xpr", "application/vnd.is-xpr");
		EXT_TO_CONTENT_TYPE.put("xps", "application/vnd.ms-xpsdocument");
		EXT_TO_CONTENT_TYPE.put("xpw", "application/vnd.intercon.formnet");
		EXT_TO_CONTENT_TYPE.put("xslt", "application/xslt+xml");
		EXT_TO_CONTENT_TYPE.put("xsm", "application/vnd.syncml+xml");
		EXT_TO_CONTENT_TYPE.put("xspf", "application/xspf+xml");
		EXT_TO_CONTENT_TYPE.put("xul", "application/vnd.mozilla.xul+xml");
		EXT_TO_CONTENT_TYPE.put("xwd", "image/x-xwindowdump");
		EXT_TO_CONTENT_TYPE.put("xyz", "chemical/x-xyz");
		EXT_TO_CONTENT_TYPE.put("yang", "application/yang");
		EXT_TO_CONTENT_TYPE.put("yin", "application/yin+xml");
		EXT_TO_CONTENT_TYPE.put("zaz", "application/vnd.zzazz.deck+xml");
		EXT_TO_CONTENT_TYPE.put("zip", "application/zip");
		EXT_TO_CONTENT_TYPE.put("zir", "application/vnd.zul");
		EXT_TO_CONTENT_TYPE.put("zmm", "application/vnd.handheld-entertainment+xml");
	}


}
